package com.bibrApp.difu.utils;

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

import com.bibrApp.difu.BeemIntent;
import com.bibrApp.difu.actvity.others.TestActivity;
import com.bibrApp.difu.api.RetrofitNet;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

public class UsbConnectUtils {

    private UsbInterface mUsbInterface;
    private UsbDeviceConnection mUsbDeviceConnection;
    private UsbEndpoint usbEndpointIn;
    private UsbEndpoint usbEndpointOut;
    private Thread mReadingthread;
    private boolean isReading;
    private UsbManager usbManager;
    private UsbDevice mUsbDevice;
    Context mContext;

    OnUsbConnectLishener lishener;
    MyHandler handler = null;


    private static class UsbConnectHelper{
        private static final UsbConnectUtils instance = new UsbConnectUtils();
    }

    private UsbConnectUtils() {

    }

    /**
     * 对外唯一实例的接口
     * @return
     */
    public static UsbConnectUtils getInstance() {
        return UsbConnectHelper.instance;
    }

    public class MyHandler extends Handler {

        public MyHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 101) {
                if (lishener != null) {
                    lishener.onReadData((List<byte[]>) msg.obj);
                }
            }
        }
    }

    public void setLishener(OnUsbConnectLishener lishener) {
        this.lishener = lishener;
    }

    public boolean isConnected() {
        return isReading;
    }


    public void init(Context context) {
        if (usbManager != null) {
            release(true);
        }

        handler = new MyHandler(context.getMainLooper());
        mContext = context;
        usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);

        IntentFilter filter = new IntentFilter(BeemIntent.ACTION_USB_INTENT);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        filter.addAction(BeemIntent.ACTION_USB_INTENT);
        mContext.registerReceiver(mUsbReceiver, filter);

        findDevice();
    }

    public void findDevice() {
        if (mUsbDevice != null && mUsbDeviceConnection != null) {
            release(false);
        }else{
            ToastUtils.ShowToast(mContext,"设备未连接或连接失败");
            DialogUtils.dismissDialog();
        }
        Log.i("ttt", "findDevice");
        HashMap<String, UsbDevice> deviceHashMap = usbManager.getDeviceList();
        Log.i("ttt", "findDevice:" + deviceHashMap.size());
        Iterator<UsbDevice> deviceIterator = deviceHashMap.values().iterator();
        while (deviceIterator.hasNext()) {
            UsbDevice device = deviceIterator.next();
            if (isTargetDevice(device)) {
                connectDevice(device);
                return;
            }
        }
    }

    public void release(boolean flag) {

        isReading = false;

        if (mUsbDeviceConnection != null) {
            mUsbDeviceConnection.releaseInterface(mUsbInterface);
            mUsbDeviceConnection.close();
            mUsbDeviceConnection = null;
            mUsbInterface = null;
        }
        if (lishener != null) {
            lishener.onDisconnect();
        }

        if (flag) {
            mContext.unregisterReceiver(mUsbReceiver);
        }
        Log.i("dj", "release");
        //
    }

    public void connectDevice(UsbDevice item) {
        Log.i("ttt", "connectDevice");
        mUsbDevice = item;
        if (usbManager.hasPermission(mUsbDevice)) {
            findIntfAndEpt();
        } else {
            getUsbPermission(mUsbDevice);
        }

    }

    private void showToast(String msg) {
        ToastUtils.ShowToast(mContext, msg);
    }

    /**
     * 寻找接口和分配结点
     */
    private void findIntfAndEpt() {
        if (mUsbDevice == null) {
            showToast("没有找到相匹配的设备");
            return;
        }
        if (mUsbDevice.getInterfaceCount() <= 0) {
            showToast("没有找到接口");
            return;
        }
        mUsbInterface = mUsbDevice.getInterface(0);
        //打开设备，获取UsbDeviceConnection对象，连接设备，用于后面的通讯
        UsbDeviceConnection usbDeviceConnection = usbManager.openDevice(mUsbDevice);
        if (usbDeviceConnection == null) {
            showToast("连接失败");
            return;
        }
        if (usbDeviceConnection.claimInterface(mUsbInterface, true)) {
            //找到接口
            mUsbDeviceConnection = usbDeviceConnection;
            //用于UsbDeviceConnection与UsbInterface进行端点设置和通讯
            getEndPoint(mUsbDeviceConnection, mUsbInterface);
            startReading();
            if (lishener != null) {
                lishener.onConnect();
            }
        } else {
            //断开连接
            usbDeviceConnection.close();
            if (lishener != null) {
                lishener.onDisconnect();
            }
        }
    }

    public int write(byte[] data) {
        if (mUsbDeviceConnection != null) {
            Log.i("dj", data.length + "----write：" + ClsPublicUtils.bytesToHex(data));
            return mUsbDeviceConnection.bulkTransfer(usbEndpointOut, data, data.length, 5000);
        }
        return -1;
    }

    public int write(List<byte[]> datas) {
        if (mUsbDeviceConnection != null) {
            int ret = -1;
            for (int i = 0; i < datas.size(); i++) {
                ret = mUsbDeviceConnection.bulkTransfer(usbEndpointOut, datas.get(i), datas.get(i).length, 5000);
            }
            return ret;
        }
        return -1;
    }

    //开线程读取数据
    private void startReading() {
        isReading = true;
        Log.i("dj", "startReading");
        mReadingthread = new Thread(new Runnable() {
            @Override
            public void run() {
                List<byte[]> list = new ArrayList<>();
                int pageNum = 0;
                while (isReading && mUsbDeviceConnection != null) {
                    synchronized (this) {
                        byte[] bytes = new byte[usbEndpointIn.getMaxPacketSize()];
                        int ret = mUsbDeviceConnection.bulkTransfer(usbEndpointIn, bytes, bytes.length, 5000);

                        if (ret > 0) {
                            Log.i("ttt", "---" + ClsPublicUtils.bytesToHex(bytes));
                            int num = Protocol.hasPageNum(bytes);
                            if (num > 0) {
                                Log.i("ttt", "---num:" + num);
                                list.clear();
                                pageNum = num;

                            }
                            list.add(bytes);
                            pageNum--;
                            if (pageNum <= 0) {
                                Message message = new Message();
                                message.what = 101;
                                message.obj = list;
                                handler.sendMessage(message);
                            }

                        }
                    }
                }
                if (mUsbDeviceConnection != null) {
                    mUsbDeviceConnection.close();
                    mUsbDeviceConnection = null;
                }
            }
        });
        mReadingthread.start();
        showToast("读取数据");
    }

    /**
     * 用UsbDeviceConnection与UsbInterface进行端点设置和通讯
     */
    private void getEndPoint(UsbDeviceConnection connection, UsbInterface usbInterface) {
        if (usbInterface.getEndpoint(0) != null) {
            usbEndpointIn = usbInterface.getEndpoint(0);
        }
        if (usbInterface.getEndpoint(1) != null) {
            usbEndpointOut = usbInterface.getEndpoint(1);
        }
    }

    //开始申请USB权限
    private void getUsbPermission(UsbDevice mUSBDevice) {

        PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(BeemIntent.ACTION_USB_INTENT), 0);
        usbManager.requestPermission(mUSBDevice, pendingIntent); // 该代码执行后，系统弹出一个对话框/等待权限
    }

    public static boolean isTargetDevice(UsbDevice device) {
        if (device.getVendorId() == 0x1209 && device.getProductId() == 0x53C1) {//找到我们的usb设备
            return true;
        }
        return false;
    }

    public interface OnUsbConnectLishener {
         void onConnect();

         void onDisconnect();

         void onReadData(List<byte[]> data);
    }

    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
            if (!UsbConnectUtils.isTargetDevice(device)) {
                return;
            }
            if (BeemIntent.ACTION_USB_INTENT.equals(action)) {
                synchronized (this) {
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        //TODO 授权成功，操作USB设备
                        showToast("usb授权成功");
                        connectDevice(device);
                    } else {
                        //用户点击拒绝了
                        showToast("拒绝usb授权");
                    }
                }
            } else if (action.equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
                showToast("插入设备");
                findDevice();
            } else if (action.equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {
                showToast("拔出设备");
                //拔出usb
                release(false);
            }

        }
    };
}
